package com.smart.system.service.impl;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.common.constant.GlobalConstants;
import com.smart.common.core.domain.entity.SysDept;
import com.smart.common.core.page.PageQuery;
import com.smart.common.exception.ServiceException;
import com.smart.common.utils.DateUtils;
import com.smart.common.utils.SecurityUtils;
import com.smart.common.utils.spring.SpringUtils;
import com.smart.system.domain.*;
import com.smart.system.domain.dto.BoundCarDto;
import com.smart.system.domain.dto.BoundEmployeeDto;
import com.smart.system.domain.vo.AreaScreenVo;
import com.smart.system.domain.vo.AreaVo;
import com.smart.system.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.system.mapper.AreaMapper;
import org.springframework.transaction.annotation.Transactional;

/**
 * 区域Service业务层处理
 * 
 * @author smart
 * @date 2024-09-18
 */
@Service
public class AreaServiceImpl extends ServiceImpl<AreaMapper,Area> implements IAreaService {

    @Autowired
    private IAreaEmployeeService areaEmployeeService;

    @Autowired
    private ICarService carService;

    @Autowired
    private IAreaCarService areaCarService;

    @Autowired
    private IEmployeeService employeeService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private IBucketService bucketService;

    @Autowired
    private IWorkingScheduleService workingScheduleService;

    @Autowired
    private IAreaService areaService;

    @Autowired
    private IAlarmService alarmService;

    @Autowired
    private IAttendanceRecordService attendanceRecordService;

    @Autowired
    private IBucketCapacityRecordService bucketCapacityRecordService;

    @Autowired
    private IEmployeeTrajectoryService employeeTrajectoryService;

    @Autowired
    private IGasRecordService gasRecordService;

    /**
     * 查询区域
     * 
     * @param id 区域主键
     * @return 区域
     */
    @Override
    public Area selectAreaById(Integer id)
    {
        return this.baseMapper.selectById(id);
    }

    /**
     * 查询区域列表
     * 
     * @param
     * @return 区域
     */
    @Override
    public IPage<AreaVo> selectAreaList(String content, Page page)
    {
        List<SysDept> sysDepts = Collections.emptyList();
        if (!SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            sysDepts = sysDeptService.listDeptChildById(SecurityUtils.getDeptId());
        }
        IPage<Area> list = this.page(page,Wrappers.lambdaQuery(Area.class)
                        .in(sysDepts.size()>0,Area::getDeptId,sysDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList()))
                .apply(content!=null,"exists(select 1 from area_car ac left join car c on ac.car_id = c.id where car_number like concat('','"+content+"',''))")
                .or(content!=null,o->o.apply("exists(select 1 from employee where name like concat('','"+content+"',''))"))
                .or(content!=null,o->o.apply("exists(select 1 from area_car ac left join car c on ac.car_id = c.id where name like concat('','"+content+"',''))"))
        );
        Page<AreaVo> resPage = new Page<>();
        BeanUtils.copyProperties(list,resPage,"records");
        resPage.setRecords(new LinkedList<>());
        for (Area record : list.getRecords()) {
            AreaVo areaVo = new AreaVo();
            BeanUtils.copyProperties(record,areaVo);
            List<AreaEmployee> areaEmployees = areaEmployeeService.list(Wrappers.lambdaQuery(AreaEmployee.class).eq(AreaEmployee::getAreaId,record.getId()));
            List<AreaCar> areaCars = areaCarService.list(Wrappers.lambdaQuery(AreaCar.class).eq(AreaCar::getAreaId,record.getId()));

            if(areaEmployees.size()>0){
                List<Integer> employeeIds = areaEmployees.stream().map(AreaEmployee::getEmployeeId).collect(Collectors.toList());
                List<Employee> employees = employeeService.listByIds(employeeIds);
                areaVo.setEmployees(employees);
            }
            if(areaCars.size()>0){
                List<Integer> carIds = areaCars.stream().map(AreaCar::getCarId).collect(Collectors.toList());
                List<Car> cars = carService.listByIds(carIds);
                areaVo.setCars(cars);
            }
            resPage.getRecords().add(areaVo);
        }
        return resPage;
    }

    /**
     * 新增区域
     * 
     * @param area 区域
     * @return 结果
     */
    @Override
    public int insertArea(Area area)
    {
        area.setCreateTime(DateUtils.getNowDate());
        return this.baseMapper.insert(area);
    }

    /**
     * 修改区域
     * 
     * @param area 区域
     * @return 结果
     */
    @Override
    public int updateArea(Area area)
    {
        area.setUpdateTime(DateUtils.getNowDate());
        return this.baseMapper.updateById(area);
    }

    /**
     * 批量删除区域
     * 
     * @param ids 需要删除的区域主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteAreaByIds(Integer[] ids)
    {
        //同时删除区域绑定人员
        areaEmployeeService.remove(Wrappers.<AreaEmployee>lambdaQuery().in(AreaEmployee::getAreaId,Arrays.asList(ids)));
        //同时删除区域绑定车辆
        areaCarService.remove(Wrappers.<AreaCar>lambdaQuery().in(AreaCar::getAreaId,Arrays.asList(ids)));
        return this.baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除区域信息
     * 
     * @param id 区域主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteAreaById(Integer id)
    {
        //先删除所有绑定的车辆关联
        areaCarService.remove(Wrappers.<AreaCar>lambdaQuery().eq(AreaCar::getAreaId,id));
        return this.baseMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean boundEmployee(BoundEmployeeDto dto) {
        Integer areaId = dto.getAreaId();
        //删除所有之前在区域中的员工
        areaEmployeeService.remove(Wrappers.<AreaEmployee>lambdaQuery().eq(AreaEmployee::getAreaId,areaId));

        if(dto.getEmployeeIds().size()>0){
            //判断绑定表中是否存在集合中任意一个人员,如果存在则返回报错
            List<AreaEmployee> exists = areaEmployeeService.list(Wrappers.lambdaQuery(AreaEmployee.class).in(AreaEmployee::getEmployeeId,dto.getEmployeeIds()));
            if(exists.size()>0){
                throw new ServiceException("其他区域中已存在所选员工,请先解绑!");
            }
        }

        List<Integer> employeeIds = dto.getEmployeeIds();
        List<AreaEmployee> areaEmployees = new LinkedList<>();
        for (Integer employeeId : employeeIds) {
            AreaEmployee areaEmployee = AreaEmployee.builder().areaId(areaId).employeeId(employeeId).build();
            areaEmployees.add(areaEmployee);
        }
        return areaEmployeeService.saveBatch(areaEmployees);
    }

    @Override
    public IPage<Employee> listEmployee(Integer areaId,String name,PageQuery pageQuery) {
        List<AreaEmployee> list = areaEmployeeService.list(Wrappers.lambdaQuery(AreaEmployee.class).eq(AreaEmployee::getAreaId,areaId));
        List<Integer> employeeIds = list.stream().map(AreaEmployee::getEmployeeId).collect(Collectors.toList());
        Area area = this.getById(areaId);
        Page<Employee> page = null;
        //判断是否未超级管理员
        if (!SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            List<SysDept> sysDepts = sysDeptService.listDeptChildById(Long.parseLong(area.getDeptId()));
            List<Long> deptIds = sysDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
            //只查询该区域部门或下级部门的的员工
            page = employeeService.page(pageQuery.toPage(), Wrappers.lambdaQuery(Employee.class).in(Employee::getDeptId,deptIds).like(name!=null,Employee::getName, name ));
            for (Employee record : page.getRecords()) {
                if (employeeIds.contains(record.getId())) {
                    record.setIsChecked(GlobalConstants.YES_CHECKED);
                    continue;
                }
                record.setIsChecked(GlobalConstants.NO_CHECKED);
            }
        }else{
            page = employeeService.page(pageQuery.toPage(), Wrappers.lambdaQuery(Employee.class).like(name!=null,Employee::getName, name ));
            for (Employee record : page.getRecords()) {
                if (employeeIds.contains(record.getId())) {
                    record.setIsChecked(GlobalConstants.YES_CHECKED);
                    continue;
                }
                record.setIsChecked(GlobalConstants.NO_CHECKED);
            }
        }


        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean boundCars(BoundCarDto dto) {
        if(dto.getCarIds()==null||dto.getCarIds().size()==0){
            throw new ServiceException("请选择车辆!");
        }
        Integer areaId = dto.getAreaId();
        //删除所有之前绑定的车辆,并且清除所选车辆跟其他区域的绑定
        areaCarService.remove(Wrappers.<AreaCar>lambdaQuery().eq(AreaCar::getAreaId,areaId).or(o->o.in(AreaCar::getCarId, dto.getCarIds())));

        //查询绑定表中是否存在集合任何一个车辆,如果存在,则提示错误
        List<Integer> carIds = dto.getCarIds();
        if(carIds.size()>0){
            List<AreaCar> size = areaCarService.list(Wrappers.lambdaQuery(AreaCar.class).in(AreaCar::getCarId, carIds).last("limit 1"));
            if(size.size()>0){
                throw new ServiceException("绑定车辆已存在!");
            }
        }
        List<Integer> employeeIds = dto.getCarIds();
        List<AreaCar> areaCars = new LinkedList<>();
        for (Integer areaCar : employeeIds) {
            AreaCar areaEmployee = AreaCar.builder().areaId(areaId).carId(areaCar).build();
            areaCars.add(areaEmployee);
        }
        return areaCarService.saveBatch(areaCars);
    }

    @Override
    public IPage<Car> listCars(Integer areaId,String content, PageQuery pageQuery) {
        List<AreaCar> list = areaCarService.list(Wrappers.lambdaQuery(AreaCar.class).eq(AreaCar::getAreaId,areaId));
        List<Integer> cars = list.stream().map(AreaCar::getCarId).collect(Collectors.toList());
        //根据区域部门获取车辆
        Area area = this.getById(areaId);
        if(area==null){
            throw new ServiceException("区域为空!");
        }
        //查询该区域绑定的部门及子部门
        List<SysDept> sysDepts = sysDeptService.listDeptChildById(Long.parseLong(area.getDeptId()));
        List<Long> deptIds = sysDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
        IPage<Car> page = carService.page(pageQuery.toPage(), Wrappers.lambdaQuery(Car.class)
                .in(Car::getDeptId, deptIds)
                .or(content!=null,o->o.like(Car::getName,content))
                .or(content!=null,o->o.like(Car::getCarNumber,content))
        );
        for (Car record : page.getRecords()) {
            if(cars.contains(record.getId())){
                record.setIsChecked(GlobalConstants.YES_CHECKED);
            }
            record.setIsChecked(GlobalConstants.NO_CHECKED);
        }
        return page;
    }

    @Override
    public List<Integer> listEmployeeIds(Integer areaId) {
        Area area = selectAreaById(areaId);
        if(area == null){
            throw new ServiceException("区域数据不存在!");
        }
        List<AreaEmployee> list = areaEmployeeService.list(Wrappers.lambdaQuery(AreaEmployee.class).eq(AreaEmployee::getAreaId, areaId));
        return list.stream().map(AreaEmployee::getEmployeeId).collect(Collectors.toList());
    }

    @Override
    public List<Integer> listCarsIds(Integer areaId) {
        Area area = selectAreaById(areaId);
        if(area == null){
            throw new ServiceException("区域数据不存在!");
        }
        List<AreaCar> list = areaCarService.list(Wrappers.lambdaQuery(AreaCar.class).eq(AreaCar::getAreaId, areaId));
        return list.stream().map(AreaCar::getCarId).collect(Collectors.toList());
    }

    @Override
    public Map getMapData(Integer areaId) {
        // 查询人员告警信息,只查询半个小时内
        List<Alarm> employeeAlarms = alarmService.list(Wrappers.lambdaQuery(Alarm.class)
                .eq(Alarm::getStatus, GlobalConstants.DEL_FLAG_NO)
                .eq(Alarm::getType, Alarm.EMPLOYEE)
                .ge(Alarm::getCreateTime, DateUtils.addMinutes(new Date(), -30))
                .orderByDesc(Alarm::getCreateTime));

        HashMap<String, Object> map = new HashMap<>();
        List<Employee> employees = employeeService.list();
        List<Car> cars = carService.list();

        // 只查询垃圾站类型的数据
        List<Bucket> platforms = bucketService.list(Wrappers.lambdaQuery(Bucket.class)
                .eq(Bucket::getType, GlobalConstants.BUCKET_TYPE_BUCKET_PLATFORM));

        // 人员
        List<Map> resEmployee = new LinkedList<Map>();
        for (Employee employee : employees) {
            Map resEmployeeMap = new HashMap();
            resEmployeeMap.put("id", employee.getId());
            resEmployeeMap.put("name", employee.getName());
            resEmployeeMap.put("photo", employee.getPhoto());
            resEmployeeMap.put("phone", employee.getPhone());
            AreaLocation location = employeeService.getLocation(employee.getId());
            resEmployeeMap.put("location", location);
            resEmployeeMap.put("alarms", Alarm.distinct(employeeAlarms));
            if(Alarm.distinct(employeeAlarms).size()==0){
                resEmployeeMap.put("employeeStatus",0);
            }else{
                resEmployeeMap.put("employeeStatus",1);
            }

            // 考勤状态
            // 获取当天考勤信息
            AttendanceRecord one = attendanceRecordService.getOne(Wrappers.lambdaQuery(AttendanceRecord.class)
                    .eq(AttendanceRecord::getUserId, employee.getId())
                    .eq(AttendanceRecord::getAttendanceDate, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date()))
                    .last("limit 1"));
            if(one!=null){
                resEmployeeMap.put("attendanceStatus", one.getAttendance());
                // 上班时间
                resEmployeeMap.put("upTime", one.getAttendanceUpTime());
                // 下班时间
                resEmployeeMap.put("downTime", one.getAttendanceDownTime());
            }else{
                resEmployeeMap.put("attendanceStatus", 4);
            }

            // 考勤次数
            resEmployeeMap.put("attendanceCount", attendanceRecordService.count(Wrappers.lambdaQuery(AttendanceRecord.class)));

            // 查询本月考勤次数
            List<AttendanceRecord> list = attendanceRecordService.list(Wrappers.lambdaQuery(AttendanceRecord.class)
                    .eq(AttendanceRecord::getUserId, employee.getId())
                    .ge(AttendanceRecord::getAttendanceDate, DateUtils.getFirstDayOfMonth()));

            // 使用map对考勤次数进行分组
            Map<String, Long> collect = list.stream().collect(Collectors.groupingBy(o -> o.getAttendance(), Collectors.counting()));

            // 考勤;0正常1迟到2旷工3请假4异常5休息
            // 将考勤分组数据返回给前端
            resEmployeeMap.put("attendanceMap", collect);

            // 本月工作时长
            resEmployeeMap.put("attendanceWorkTime", list.stream()
                    .filter(o -> o.getAttendanceDownTime() != null && o.getAttendanceUpTime() != null)
                    .mapToLong(o -> o.getAttendanceDownTime().getHours() - o.getAttendanceUpTime().getHours())
                    .sum());

            // 本月工作天数
            resEmployeeMap.put("attendanceWorkDay", list.stream().filter(o->"0".equals(o.getAttendance())).mapToLong(o->o.getAttendanceDate().getTime()).distinct().count());

            // 工作里程
            // 获取员工上班时间
            LambdaQueryWrapper<EmployeeTrajectory> wrapper = Wrappers.lambdaQuery(EmployeeTrajectory.class);
            wrapper.eq(EmployeeTrajectory::getUserId,employee.getId());
            if(one!=null){
                if(one.getAttendanceUpTime()!=null){
                    wrapper.ge(EmployeeTrajectory::getCreateTime,one.getAttendanceUpTime());
                    if(one.getAttendanceDownTime()==null){
                        wrapper.le(EmployeeTrajectory::getCreateTime,DateUtils.getNowDate());
                    }
                }
                if(one.getAttendanceDownTime()!=null&&one.getAttendanceUpTime()!=null){
                    wrapper.le(EmployeeTrajectory::getCreateTime,one.getAttendanceUpTime());
                }
                if(!(one.getAttendanceDownTime()==null&&one.getAttendanceUpTime()==null)){
                    List<EmployeeTrajectory> employeeTrajectories = employeeTrajectoryService.list(wrapper);
                    if(employeeTrajectories.size()>0){
                        List<AreaLocation> locations = employeeTrajectories.stream().map(EmployeeTrajectory::getAreaLocation).collect(Collectors.toList());
                        // 先对原始坐标点进行抽稀
                        int locationSize = (int) (locations.size()*0.01);
                        if (locationSize<5) {
                            locationSize = 10;
                        }
                        List<AreaLocation> simplify = EnhancedTrajectorySimplifier.simplify(locations,locationSize , true);
                        // 计算里程
                        double km = AreaLocation.calculateTotalDistance(simplify);
                        // 保留两位小数
                        resEmployeeMap.put("workingMileage",String.format("%.2f",km));
                    }
                }else{
                    resEmployeeMap.put("workingMileage","0");
                }
            }else{
                resEmployeeMap.put("workingMileage","0");
            }

            // 更新时间
            resEmployeeMap.put("locationTime",new Date());
            // 获取人员轨迹
            resEmployee.add(resEmployeeMap);
        }
        map.put("employees",resEmployee);

        // 查询车辆告警信息
        List<Alarm> carAlarms = alarmService.list(Wrappers.lambdaQuery(Alarm.class)
                .eq(Alarm::getStatus, GlobalConstants.DEL_FLAG_NO)
                .eq(Alarm::getType, Alarm.CAR)
                .orderByDesc(Alarm::getCreateTime));

        // 车辆
        List<Map> resCar = new LinkedList<Map>();
        for (Car car : cars) {
            Map resCarMap = new HashMap();
            resCarMap.put("id", car.getId());
            resCarMap.put("name", car.getName());
            resCarMap.put("carNumber", car.getCarNumber());
            Employee carEmployee =  employeeService.getById(car.getDriverId());
            if(carEmployee!=null){
                resCarMap.put("driverPhone", carEmployee.getPhone());
                resCarMap.put("driver", carEmployee.getName());
            }

            CarTrajectory carTrajectory = carService.getLocation(car.getId());
            if(carTrajectory==null){
                resCarMap.put("location", "");
                resCarMap.put("locationTime", DateUtils.getDate());
            }else{
                resCarMap.put("locationTime", carTrajectory.getCreateTime());
                resCarMap.put("location", carTrajectory.getAreaLocation());
            }

            // 车辆告警信息
            resCarMap.put("alarms", Alarm.distinct(carAlarms));
            resCar.add(resCarMap);
        }
        map.put("cars",resCar);

        // 查询垃圾站告警信息,只有垃圾站会有告警
//        List<Alarm> bucketAlarms = alarmService.list(Wrappers.lambdaQuery(Alarm.class)
//                .eq(Alarm::getStatus, GlobalConstants.DEL_FLAG_NO)
//                .eq(Alarm::getType, Alarm.BUCKET)
//                .orderByDesc(Alarm::getCreateTime)
//                .last("limit 200")
//        );


        // 垃圾站(只保留platform类型)
        List<Map> resPlatform = new LinkedList<Map>();
        for (Bucket platform : platforms) {
            //垃圾站气体监测
            GasRecord one = gasRecordService.getOne(Wrappers.lambdaQuery(GasRecord.class)
                    .eq(GasRecord::getBucketId, platform.getId())
                    .orderByDesc(GasRecord::getCreateTime)
                    .last("limit 1")
            );
            Map resPlatformMap = new HashMap();
            resPlatformMap.put("gas",one);
            resPlatformMap.put("id", platform.getId());
            resPlatformMap.put("name", platform.getName());
            resPlatformMap.put("location", platform.getAreaLocation());
            // 最大容量
            resPlatformMap.put("maxCapacity",platform.getCapacity());
            // 当前容量
//            resPlatformMap.put("capacity",convertToPercentage(platform.getThreshold()));
            resPlatformMap.put("capacity",platform.getThreshold());
            Map<String, Object> bucketMap = bucketCapacityRecordService.get(DateUtils.getStartTime(), DateUtils.getEndTime(), Arrays.asList(platform.getId()));
            List<Map<String, Object>> list = (List<Map<String, Object>>) bucketMap.get("list");
            // 获取垃圾桶的总容量
            double thresholdValue = platform.getThresholdValue();
            double disposalToday = 0;
            int capacity = Integer.parseInt(platform.getCapacity());
            // 今日处理垃圾
            for (Map<String, Object> record : list) {
                List number = ((List)record.get("number"));
                for (Object o: number) {
                    disposalToday += capacity * (Double)o * 0.01;
                }
            }
            // 更新时间
            resPlatformMap.put("locationTime",new Date());
            resPlatformMap.put("disposalToday", disposalToday);
            // 视频url
            List<String> videoUrl = bucketService.getVideoUrl(String.valueOf(platform.getId()));
            resPlatformMap.put("videoUrls",videoUrl);
            // 本月垃圾处理
            Map<String, Object> bucketMap1 = bucketCapacityRecordService.get(DateUtils.getFirstDayOfMonth(), DateUtils.getLastDayOfMonth(), Arrays.asList(platform.getId()));
            List<Map<String, Object>> list1 = (List<Map<String, Object>>) bucketMap1.get("list");

            double disposalThisMonth = 0;
            for (Map<String, Object> record : list1) {
                List number = ((List)record.get("number"));
                for (Object  o: number) {
                    disposalThisMonth += capacity * (Double)o * 0.01;
                }
            }
            resPlatformMap.put("disposalThisMonth", disposalThisMonth);
            // 垃圾总增长量
            // 获取上月垃圾处理量
            Map<String, Object> bucketMap2 = bucketCapacityRecordService.get(DateUtils.getFirstDayOfLastMonth(), DateUtils.getLastDayOfLastMonth(), Arrays.asList(platform.getId()));
            List<Map<String, Object>> list2 = (List<Map<String, Object>>) bucketMap2.get("list");

            double disposalLastMonth = 0;
            for (Map<String, Object> record : list2) {
                List number = ((List)record.get("number"));
                for (Object  o: number) {
                    disposalLastMonth += capacity * (Double)o * 0.01;
                }
            }

            // 计算垃圾增长量
            double disposalGrowth = disposalThisMonth - disposalLastMonth;
            resPlatformMap.put("disposalGrowth", disposalGrowth);
            List<Alarm> bucketAlarms = new LinkedList<>();
            Alarm alarm = Alarm.builder()
                    .type(GlobalConstants.TRASH_CAN)
                    .toId(platform.getId())
                    .message(Alarm.Message.REACH_THRESHOLD.getCode())
                    .areaId(areaId)
                    .createTime(new Date())
                    .build();
            if(platform.getThreshold()>thresholdValue){
                bucketAlarms.add(alarm);
            }
            resPlatformMap.put("alarms", Alarm.distinct(bucketAlarms));
            resPlatform.add(resPlatformMap);
        }
        map.put("platforms",resPlatform);

        // 区域
        Area area = selectAreaById(areaId);
        map.put("area",area);
        return map;
    }

    /**
     * 将4-19范围内的数值转换为百分比
     * 4对应0%，19对应100%
     *
     * @param value 4-19范围内的数值
     * @return 对应的百分比值(0-100)
     */
    public int convertToPercentage(double value) {
        // 限制输入值在4-19范围内
        value = Math.max(4, Math.min(19, value));

        // 使用线性映射公式: (value - min) / (max - min) * 100
        return (int) Math.round((value - 4) / (19 - 4) * 100);
    }

    @Override
    public Map getWorkMonitor() {
        HashMap<Object, Object> resMap = new HashMap<>();
        //获取所有部门,并且获取上班日期
        List<SysDept> depts = sysDeptService.list();
        int carCount = 0;
        int employeeCount = 0;
        for (SysDept dept : depts) {
            WorkingSchedule workingSchedule = workingScheduleService.getOne(Wrappers.lambdaQuery(WorkingSchedule.class)
                    .eq(WorkingSchedule::getDeptId, dept.getDeptId()).last("limit 1")
            );
            if(workingSchedule==null||!workingSchedule.isWorkDay()){
                continue;
            }
            List<Area> areas = areaService.list(Wrappers.lambdaQuery(Area.class).eq(Area::getDeptId, dept.getDeptId()));
            if (areas.size()>0) {
                List<AreaEmployee> list = areaEmployeeService.list(Wrappers.lambdaQuery(AreaEmployee.class).in(AreaEmployee::getAreaId, areas.stream().map(Area::getId).collect(Collectors.toList())));
                employeeCount += list.size();
                List<AreaCar> list1 = areaCarService.list(Wrappers.lambdaQuery(AreaCar.class).in(AreaCar::getAreaId, areas.stream().map(Area::getId).collect(Collectors.toList())));
                carCount += list1.size();
            }
        }
        resMap.put("carCount",carCount);
        resMap.put("employeeCount",employeeCount);
        return resMap;
    }

    @Override
    public boolean unBoundEmployee(BoundEmployeeDto dto) {
        if(dto.getAreaId()==null){
            throw new ServiceException("请填写区域id");
        }
        if(dto.getEmployeeIds().size() == 0){
            throw new ServiceException("请选择人员");
        }
        return areaEmployeeService.remove(Wrappers.lambdaQuery(AreaEmployee.class)
                .eq(AreaEmployee::getAreaId, dto.getAreaId())
                .in(AreaEmployee::getEmployeeId, dto.getEmployeeIds()));
    }

    @Override
    public boolean unBoundCars(BoundCarDto dto) {
        if(dto.getAreaId()==null){
            throw new ServiceException("请填写区域id");
        }
        if(dto.getCarIds().size() == 0){
            throw new ServiceException("请选择车辆");
        }
        return areaCarService.remove(Wrappers.lambdaQuery(AreaCar.class)
                .eq(AreaCar::getAreaId, dto.getAreaId())
                .in(AreaCar::getCarId, dto.getCarIds()));
    }


    @Override
    public IPage<AreaScreenVo> listScreenArea(Page toPage) {
        IPage<Area> page = this.page(toPage, Wrappers.lambdaQuery(Area.class));
        List<Area> areaList = page.getRecords();
        IPage<AreaScreenVo> resPage = new Page<>();
        BeanUtils.copyProperties(page, resPage,"records");
        ArrayList<AreaScreenVo> resList = new ArrayList<>();
        for (Area area : areaList) {
            AreaScreenVo areaScreenVo = new AreaScreenVo();
            areaScreenVo.setId(area.getId());
            areaScreenVo.setName(area.getName());
            //查询区域下人员总数+车辆总数+垃圾桶/垃圾站总数相加
            List<AreaEmployee> list = areaEmployeeService.list(Wrappers.lambdaQuery(AreaEmployee.class).eq(AreaEmployee::getAreaId, area.getId()));
            List<AreaCar> list1 = areaCarService.list(Wrappers.lambdaQuery(AreaCar.class).eq(AreaCar::getAreaId, area.getId()));
            areaScreenVo.setNumber(list.size()+list1.size());
            resList.add(areaScreenVo);
        }
        resPage.setRecords(resList);
        return resPage;
    }
}
